﻿using System;
using System.ComponentModel;
using System.Data.Linq;
using System.Data.Linq.Mapping;

namespace Data.MappingClasses
{
    [TableAttribute(Name = "dbo.Street")]
    public partial class Street : AbstractMappingClass, INotifyPropertyChanging, INotifyPropertyChanged
    {

        private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);

        private short _idStreet;

        private short _refTown;

        private short _refStreetType;

        private string _nameStreet;

        private EntitySet<Address> _Addresses;

        private EntityRef<StreetType> _StreetType;

        private EntityRef<Town> _Town;

        #region Extensibility Method Definitions
        partial void OnLoaded();
        partial void OnValidate(ChangeAction action);
        partial void OnCreated();
        partial void OnidStreetChanging(short value);
        partial void OnidStreetChanged();
        partial void OnrefTownChanging(short value);
        partial void OnrefTownChanged();
        partial void OnrefStreetTypeChanging(short value);
        partial void OnrefStreetTypeChanged();
        partial void OnnameStreetChanging(string value);
        partial void OnnameStreetChanged();
        #endregion

        public Street()
        {
            this._Addresses = new EntitySet<Address>(AttachAddresses, DetachAddresses);
            this._StreetType = default(EntityRef<StreetType>);
            this._Town = default(EntityRef<Town>);
            OnCreated();
        }

        [ColumnAttribute(Storage = "_idStreet", AutoSync = AutoSync.OnInsert, DbType = "SmallInt NOT NULL IDENTITY", IsPrimaryKey = true, IsDbGenerated = true)]
        public short idStreet
        {
            get
            {
                return this._idStreet;
            }
            set
            {
                if ((this._idStreet != value))
                {
                    this.OnidStreetChanging(value);
                    this.SendPropertyChanging();
                    this._idStreet = value;
                    this.SendPropertyChanged("idStreet");
                    this.OnidStreetChanged();
                }
            }
        }

        [ColumnAttribute(Storage = "_refTown", DbType = "SmallInt NOT NULL")]
        public short refTown
        {
            get
            {
                return this._refTown;
            }
            set
            {
                if ((this._refTown != value))
                {
                    if (this._Town.HasLoadedOrAssignedValue)
                    {
                        throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
                    }
                    this.OnrefTownChanging(value);
                    this.SendPropertyChanging();
                    this._refTown = value;
                    this.SendPropertyChanged("refTown");
                    this.OnrefTownChanged();
                }
            }
        }

        [ColumnAttribute(Storage = "_refStreetType", DbType = "SmallInt NOT NULL")]
        public short refStreetType
        {
            get
            {
                return this._refStreetType;
            }
            set
            {
                if ((this._refStreetType != value))
                {
                    if (this._StreetType.HasLoadedOrAssignedValue)
                    {
                        throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
                    }
                    this.OnrefStreetTypeChanging(value);
                    this.SendPropertyChanging();
                    this._refStreetType = value;
                    this.SendPropertyChanged("refStreetType");
                    this.OnrefStreetTypeChanged();
                }
            }
        }

        [ColumnAttribute(Storage = "_nameStreet", DbType = "VarChar(255) NOT NULL", CanBeNull = false)]
        public string nameStreet
        {
            get
            {
                return this._nameStreet;
            }
            set
            {
                if ((this._nameStreet != value))
                {
                    this.OnnameStreetChanging(value);
                    this.SendPropertyChanging();
                    this._nameStreet = value;
                    this.SendPropertyChanged("nameStreet");
                    this.OnnameStreetChanged();
                }
            }
        }

        [AssociationAttribute(Name = "Street_Address", Storage = "_Addresses", ThisKey = "idStreet", OtherKey = "refStreet")]
        public EntitySet<Address> Addresses
        {
            get
            {
                return this._Addresses;
            }
            set
            {
                this._Addresses.Assign(value);
            }
        }

        [AssociationAttribute(Name = "StreetType_Street", Storage = "_StreetType", ThisKey = "refStreetType", OtherKey = "idStreetType", IsForeignKey = true)]
        public StreetType StreetType
        {
            get
            {
                return this._StreetType.Entity;
            }
            set
            {
                StreetType previousValue = this._StreetType.Entity;
                if (((previousValue != value)
                     || (this._StreetType.HasLoadedOrAssignedValue == false)))
                {
                    this.SendPropertyChanging();
                    if ((previousValue != null))
                    {
                        this._StreetType.Entity = null;
                        previousValue.Streets.Remove(this);
                    }
                    this._StreetType.Entity = value;
                    if ((value != null))
                    {
                        value.Streets.Add(this);
                        this._refStreetType = value.idStreetType;
                    }
                    else
                    {
                        this._refStreetType = default(short);
                    }
                    this.SendPropertyChanged("StreetType");
                }
            }
        }

        [AssociationAttribute(Name = "Town_Street", Storage = "_Town", ThisKey = "refTown", OtherKey = "idTown", IsForeignKey = true)]
        public Town Town
        {
            get
            {
                return this._Town.Entity;
            }
            set
            {
                Town previousValue = this._Town.Entity;
                if (((previousValue != value)
                     || (this._Town.HasLoadedOrAssignedValue == false)))
                {
                    this.SendPropertyChanging();
                    if ((previousValue != null))
                    {
                        this._Town.Entity = null;
                        previousValue.Streets.Remove(this);
                    }
                    this._Town.Entity = value;
                    if ((value != null))
                    {
                        value.Streets.Add(this);
                        this._refTown = value.idTown;
                    }
                    else
                    {
                        this._refTown = default(short);
                    }
                    this.SendPropertyChanged("Town");
                }
            }
        }

        public event PropertyChangingEventHandler PropertyChanging;

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void SendPropertyChanging()
        {
            if ((this.PropertyChanging != null))
            {
                this.PropertyChanging(this, emptyChangingEventArgs);
            }
        }

        protected virtual void SendPropertyChanged(String propertyName)
        {
            if ((this.PropertyChanged != null))
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        private void AttachAddresses(Address entity)
        {
            this.SendPropertyChanging();
            entity.Street = this;
        }

        private void DetachAddresses(Address entity)
        {
            this.SendPropertyChanging();
            entity.Street = null;
        }

        public override Model.ModelClasses.AbstractModel PureModel
        {
            get
            {
                return base.PureModel;
            }
            set
            {
                if (_pureModel != null)
                    _pureModel.UpdateModelEvent -= UpdateModelEventHandler;

                _pureModel = value;

                if (value != null)
                    value.UpdateModelEvent += UpdateModelEventHandler;
            }
        }

        private void UpdateModelEventHandler(object sender, EventArgs e)
        {
            nameStreet = ((Model.Interfaces.IStreet) PureModel).Name;
            // обновление города и типа улицы происходит уровнем выше (в DataDispatcher)
            UpdateData();
        }
    }
}